﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IndignadoFramework.BackBone.Model;
using IndignadoFramework.DataAccessLayer.EntityModels;
using System.Data.Entity;
using System.Data.Objects;


namespace IndignadoFramework.BackBone.InternalServices.Implementacion
{
    public class UsuarioServicesImpl : UsuarioServices
    {
        public int addUsuario(UsuarioModel u)
        {
            Usuario usuarioEntity = new Usuario();

            AutoMapper.Mapper.CreateMap<UsuarioModel, Usuario>();
            usuarioEntity = AutoMapper.Mapper.Map(u, usuarioEntity);
            usuarioEntity.CategoriaTematica = new List<CategoriaTematica>();

            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                if (!context.Usuarios.Any(usr => ((usr.UsuarioRedSocial.Equals("F") && usr.UsuarioFacebook == u.UsuarioFacebook)
                            || (usr.UsuarioRedSocial.Equals("T") && usr.UsuarioTwitter == u.UsuarioTwitter))
                        && usr.MovimientoId == u.MovimientoId))
                {
                    List<CategoriaTematica> listCategorias = context.CategoriasTematicas.ToList();
                    for (int i = 0; i < u.CategoriasTematicas.Count(); i++)
                    {
                        CategoriaTematica categoria = listCategorias.Find(c => c.CategoriaTematicaNombre == u.CategoriasTematicas[i]);
                        usuarioEntity.CategoriaTematica.Add(categoria);
                    }
                    context.AddObject("Usuarios", usuarioEntity);
                    context.SaveChanges();
                }
                else
                {
                    return -1;
                }
            }
            return usuarioEntity.Id;
        }

        public int existUsuario(UsuarioModel u)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                IQueryable<Usuario> usuarioEntity = (from usr in context.Usuarios
                                                        where usr.MovimientoId == u.MovimientoId
                                                        where usr.UsuarioFacebook == u.UsuarioFacebook
                                                        where usr.UsuarioRedSocial == u.UsuarioRedSocial
                                                        select usr);

                if (usuarioEntity.Any()){
                    if (usuarioEntity.Single().UsuarioDadoBaja)
                        return -2;
                    else
                        return usuarioEntity.Single().Id;
                }
                else
                    return -1;
            }
        }

        public void asistirConvocatoria(int UsuarioId, ConvocatoriaModel Convocatoria)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                Usuario usuarioEntity = context.Usuarios.FirstOrDefault(u => u.Id == UsuarioId);
                Convocatoria convocatoriaEntity = context.Convocatorias.FirstOrDefault(c => c.Id == Convocatoria.Id 
                        && c.MovimientoId == Convocatoria.MovimientoId);
                usuarioEntity.Convocatoria.Add(convocatoriaEntity);
                context.SaveChanges();
            }
        }

        public void asistirConvocatoriaUsuarioPhone(Nullable<long> facebookID, ConvocatoriaModel convocatoria)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                Usuario usuarioEntity = context.Usuarios.FirstOrDefault(u => u.UsuarioFacebook == facebookID);
                Convocatoria convocatoriaEntity = context.Convocatorias.FirstOrDefault(c => c.Id == convocatoria.Id);
                usuarioEntity.Convocatoria.Add(convocatoriaEntity);
                context.SaveChanges();
            }
        }

        public bool asistiraUsuario(int UsuarioId, ConvocatoriaModel Convocatoria)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                Usuario usuarioEntity = context.Usuarios.FirstOrDefault(u => u.Id == UsuarioId);
                Convocatoria convocatoriaEntity = context.Convocatorias.FirstOrDefault(c => c.Id == Convocatoria.Id
                        && c.MovimientoId == Convocatoria.MovimientoId);
                return usuarioEntity.Convocatoria.Contains(convocatoriaEntity);
            }
        }

        public string getNombreUsuario(int UsuarioId, int MovimientoId)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                IQueryable<Usuario> usuarioEntity = (from usr in context.Usuarios
                                                        where usr.MovimientoId == MovimientoId
                                                        where usr.Id == UsuarioId
                                                        select usr);

                if (usuarioEntity.Any())
                    return usuarioEntity.Single().UsuarioNombre;
                else
                    return null;
            }
        }

        public void loginUsuario(int UsuarioId, int MovimientoId)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                IQueryable<Usuario> usuarioEntity = (from usr in context.Usuarios
                                                     where usr.MovimientoId == MovimientoId
                                                     where usr.Id == UsuarioId
                                                     select usr);

                usuarioEntity.First().UsuarioLogueado = true;
                context.SaveChanges();
            }
        }

        public void logoutUsuario(int UsuarioId, int MovimientoId)
        {
            using (IndignadoFrameworkEntities context = new IndignadoFrameworkEntities())
            {
                IQueryable<Usuario> usuarioEntity = (from usr in context.Usuarios
                                                     where usr.MovimientoId == MovimientoId
                                                     where usr.Id == UsuarioId
                                                     select usr);

                usuarioEntity.First().UsuarioLogueado = false;
                context.SaveChanges();
            }
        }

        public IEnumerable<int> usuariosByDate()
        {
            List<int> listaUsuarios = new List<int>();
            IndignadoFrameworkEntities context = new IndignadoFrameworkEntities();
            // Selecciono todos los usuarios
            IQueryable<Usuario> usuarios = from usu in context.Usuarios 
                                           select usu;

            //Todos los registrados en el último día
            int contar = 0;
            foreach (Usuario user in usuarios)
            {
                if (DateTime.Now.Subtract(user.UsuarioFechaRegistro).Days < 1)
                    contar++;
            }
            listaUsuarios.Add(contar);

            //Todos los registrados en la última semana
            contar = 0;
            foreach (Usuario user in usuarios)
            {
                if (DateTime.Now.Subtract(user.UsuarioFechaRegistro).Days < 7)
                    contar++;
            }
            listaUsuarios.Add(contar);

            //Todos los registrados en el último mes
            contar = 0;
            foreach (Usuario user in usuarios)
            {
                if (DateTime.Now.Subtract(user.UsuarioFechaRegistro).Days < 30)
                    contar++;
            }
            listaUsuarios.Add(contar);

            //Todos los registrados en el sistema            
            listaUsuarios.Add(usuarios.Count());

            usuarios = from usu in context.Usuarios
                       where usu.UsuarioDadoBaja == false
                       select usu;

            //Todos los registrados en el sistema no dados de baja
            contar = 0;
            foreach (Usuario user in usuarios)
            {
                if (!user.UsuarioDadoBaja)
                    contar++;
            }
            listaUsuarios.Add(contar);

            return listaUsuarios;
        }
    }
}
